/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package generatorGraphics.interfaces;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.ArrayList;
import javax.swing.*;
import manager.Processor;
import org.jdesktop.swingx.JXCollapsiblePane;

/**
 *
 * @author Heitor
 */
public class JFScreen extends JFrame{
        
    private JPanel jpNorth;
    private JScrollPane jspCenter;

    public JToolBar jToolBar;
    public JXCollapsiblePane jCollapsible;
    
    private JPGraphics jpGraphics;
    private JPCategory jpCategory;
    
    private JButton jbCategory;
    private JButton jbProcessorTester;
    private JButton jbExtractor;
    
    private ArrayList<JButton> buttonsToolBar;
    
    private JFileChooser fileChooser;
    private String directory;
    
    /** 
     * Método extra para geração de icones (Em analise)
     */
    private static final GridBagConstraints gbc;  
    static {  
        gbc = new GridBagConstraints();  
        gbc.gridx = 0;  
        gbc.gridy = 0;  
        gbc.weightx = 1.0;  
        gbc.weighty = 1.0;  
        gbc.fill = GridBagConstraints.BOTH;  
        gbc.anchor = GridBagConstraints.NORTHWEST;  
    }

    public JFScreen(){

        initComponents();
        
        treatEvents();
        
        setTitle(getTitle() + "Generator Graphics");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setMinimumSize(new Dimension(750, 450));
        
        setMinimumSize(new Dimension(750, 550));
        
        setIconImage((new ImageIcon(JFScreen.class.getResource("/generatorGraphics/images/icon.png"))).getImage());
        
        //Toolkit kit = Toolkit.getDefaultToolkit();
        //Dimension tamTela = kit.getScreenSize();
        //setMaximumSize(tamTela);        
    }

    private void initComponents(){
    
        setLookAndFeel();
        /*
         * O frame será dividido em dois paineis principais.
         * O jpNorth, que irá armazena a barra de ferramentas e jXCollapsiblePane,
         * e jpCenter, este armazena o painel que mostrará o gráfico.
         */ 
        
        /*
         * JPNorth:
         */
        jpNorth = new JPanel();
            jpNorth.setLayout(new BorderLayout());

            jToolBar = new JToolBar();
            jToolBar.setBackground(new Color(211, 221, 248));
            
            buttonsToolBar = new ArrayList<>();
            
            featuresTool();
            
            /*
             * Adiciona todos os botões da barra de ferramentas (buttonsToolBar)
             */
            for(int j=0; j<buttonsToolBar.size(); j++){
                buttonsToolBar.get(j).setBackground(new Color(211, 221, 248));
                jToolBar.add(buttonsToolBar.get(j));
                if(j !=  buttonsToolBar.size()-1){
                    jToolBar.addSeparator();
                }
            }

            jCollapsible = new JXCollapsiblePane();
            jCollapsible.setAnimated(false);
            jCollapsible.setCollapsed(true);
            jCollapsible.setBackground(new Color(211, 221, 248));
            
            jpNorth.add(BorderLayout.NORTH, jToolBar);
            jpNorth.add(BorderLayout.CENTER, jCollapsible);
            jpNorth.add(BorderLayout.AFTER_LAST_LINE, new JPopupMenu.Separator(){
                    @Override
                    protected void paintComponent(Graphics g) {
                        g.setColor(Color.LIGHT_GRAY);
                        g.drawLine(0, 0, getContentPane().getWidth(), 0);
                    }
                });
        
        /*
        * JSPCenter:
        */
        jspCenter = new JScrollPane();
        
            /*
             * Instancia a classe JPGraphics:
             * - Adiciona os tipos e unidades do grafico
             * - Caso precise adiciona um botão extra (FUNCIONALIDADE AINDA NÃO IMPLEMENTADA)
             */
            jpGraphics = new JPGraphics(this, null);
                
            jspCenter.setViewportView(jpGraphics);
            jspCenter.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            jspCenter.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
            jspCenter.setBorder(null);
            
        setLayout(new BorderLayout());
        add(BorderLayout.NORTH, jpNorth);
        add(BorderLayout.CENTER, jspCenter);
        
        repaint();
        pack();

    }


    /**
     * Configura todas as caracteristicas da barra de ferramentas:
     * - Constrói botões e seus eventos
     * - Constrói paineis
     */
    private void featuresTool(){

        buttonsToolBar = new ArrayList<>();
        
        jbCategory = new JButton("Category");
        jbCategory.setIcon(new ImageIcon(JFScreen.class.getResource("/generatorGraphics/images/category_object.png")));
        jbCategory.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //screenResize();
                jbCategoryActionPerformed();
                
                //Temporario - para o artigo SBAI
                jbExtractor.setVisible(false);
            }
        });
        jbCategory.setVisible(false);
        
        //Botão apenas para O programador - Compilação de arquivos JJ
            jbProcessorTester = new JButton("Generator and Tester");
            //jbProcessorTester.setIcon(null);
            jbProcessorTester.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Processor compile = new Processor();
                    compile.setVisible(true);
                    compile.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                }
            });
        
        jbExtractor = new JButton("Extractor");
        jbExtractor.setIcon(new ImageIcon(JFScreen.class.getResource("/generatorGraphics/images/extract_object1.png")));
        jbExtractor.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int chooser = putDirectory();
                if(chooser == JFileChooser.APPROVE_OPTION){
                    for(int i=0; i<jpCategory.getCategoryList().size(); i++){
                        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                        for(int j=0; j<jpCategory.getCategoryList().get(i).getGraphicsList().size(); j++){
                            jpCategory.getCategoryList().get(i).getGraphicsList().get(j).start(directory);
                        }
                        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                    }
                    
                    jbCategory.setVisible(true);
                }
                
            }
        });
        
        buttonsToolBar.add(jbExtractor);
        buttonsToolBar.add(jbCategory);
        //buttonsToolBar.add(jbProcessorTester);
        
            
        /*
         * Constrói todos os paineis
         */
        jpCategory = new JPCategory();
        
        jpCategory.setVisible(true);
        
    }
    
    
    /**
     * Método que trata os eventos do frame
     */
    private void treatEvents(){
        
        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {  
            public void eventDispatched(AWTEvent event) {  
                String[] aux = event.paramString().split(",");
                if(aux.length>1){
                    if((event.getID() == 402)&&((aux[1].split("="))[1].equals("18"))){
                        if(jToolBar.isVisible()){
                            jToolBar.setVisible(false);
                            jCollapsible.setVisible(false);
                        }else{
                            jToolBar.setVisible(true);
                            jCollapsible.setVisible(true);
                        }
                        screenResize();
                    }
                }
            }  
        }, AWTEvent.KEY_EVENT_MASK);
        
        addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                screenResize();
            }
        });
        
        addWindowStateListener(new WindowStateListener() {

            @Override
            public void windowStateChanged(WindowEvent e) {
                screenResize();
            }
        });
       
    }
    
    /**
     * Método que trata a ação do botão de Categoria
     */
    private void jbCategoryActionPerformed(){
        
        /*
         * Setando painel de Categoria.
         * Painel sendo alocado no jCollapsible caso o botão tenha sido pressionado.
         */
        jCollapsible.add(jpCategory);
        jCollapsible.setBackground(new Color(211, 221, 248));
        
        if (jCollapsible.isCollapsed()){
            jCollapsible.setCollapsed(false);
        } else{
            jCollapsible.setCollapsed(true);
        }
        
        screenResize();
    }

    /**
     * @return the jpCategory
     */
    public JPCategory getJpCategory() {
        return jpCategory;
    }

    /**
     * @param jpCategory the jpCategory to set
     */
    public void setJpCategory(JPCategory jpCategory) {
        this.jpCategory = jpCategory;
        this.jpCategory.setVisible(true);
        
        updateJpCategory();
    }
    
    /**
     * Verifica e atualizar o jpGraphics no momento em que algum botão do jpCategory é clicado
     */
    private void checkJPGraphics(){
        
        if(jpGraphics.getCurrentCategory() != jpCategory.getCatActive()){
            jpGraphics.removeAll();
            jpGraphics = null;
            jpGraphics = new JPGraphics(this, jpCategory.getCatActive());
        }
        
        screenResize();
    }
    
    /**
     * Método que trata quando a tela é redimensionada
     */
    public void screenResize(){
        
        //Dimension curSize = getSize();
        //jpGraphics.componentGraphResize(curSize);
        jpGraphics.componentGraphResize(jspCenter.getSize());
        jpGraphics.setVisible(true);

        jspCenter.setViewportView(jpGraphics);
        jspCenter.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        jspCenter.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        jspCenter.setBorder(null);
        jspCenter.setVisible(true);
                
    }
    
    /**
     * Atualiza o painel de categoria
     */
    private void updateJpCategory(){
        
        for(int u=0; u<jpCategory.getComponents().length; u++){
            try{
                getJpCategory().getComponent(u).addMouseListener(new MouseAdapter() {

                    @Override
                    public void mouseClicked(MouseEvent e) {
                        checkJPGraphics();
                    }
                });
                
            } catch (Exception e){
                System.out.println("[Erro-JFScreen] (Talvez o jpCategory tenha algo que não seja JButton) " + e.toString());
            }
        }
        
        jpCategory.setVisible(true);
        
    }
    
    private static void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch(Exception e) {
        }
    }
    
    private int putDirectory(){
        fileChooser = new javax.swing.JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int returnVal2 = fileChooser.showOpenDialog(fileChooser);
        directory = "";
        if (returnVal2 == JFileChooser.APPROVE_OPTION) {
            File fileLoad = fileChooser.getSelectedFile();
            directory = fileLoad.getAbsolutePath();
        }
        
        return returnVal2;
    }
    
}
